﻿using PGMHelper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace OpenSees.XML
{
    /// <summary>
    /// 单元分析结果集合
    /// </summary>
    public class ElementDataSet
    {
        #region Variables

        /// <summary>
        /// 单元分析结果
        /// </summary>
        public List<ElementData> Datas { set; get; }

        /// <summary>
        /// 响应字典：不包含时间
        /// </summary>
        private Dictionary<int, ElementData> elementDict { set; get; }

        /// <summary>
        /// 力分析结果
        /// </summary>
        public ElementXML forceXML { set; get; }

        /// <summary>
        /// 变形分析结果
        /// </summary>
        public ElementXML deformXML { set; get; }

        /// <summary>
        /// 应变分析结果
        /// </summary>
        public ElementXML strainXML { set; get; }

        #endregion

        #region Properties

        /// <summary>
        /// 响应字典
        /// </summary>
        private Dictionary<int, ElementData> ElementDict
        {
            get
            {
                //实例化
                if (this.elementDict == null)
                    this.elementDict = new Dictionary<int, ElementData>(this.Datas.Count);
                //键值是否相同
                if (this.elementDict.Count == this.Datas.Count) return this.elementDict;
                //获得字典
                this.elementDict = (Dictionary<int, ElementData>)this.Datas.CreateDict<int, ElementData>("ID");
                //返回字典
                return this.elementDict;
            }
        }

        /// <summary>
        /// 获得单元分析结果
        /// </summary>
        /// <param name="tag"></param>
        /// <returns></returns>
        public ElementData this[int tag]
        {
            get
            {
                return this.ElementDict.GetValue(tag);
            }
        }

        /// <summary>
        /// 获得相同编号
        /// </summary>
        private List<int> SameTagFromXML
        {
            get
            {
                //筛选相同编号的函数指针
                Func<List<int>, List<int>, List<int>> FilterFuc = (listI, listJ) =>
                {
                    return (from tag in listI where listJ.Contains(tag) select tag).ToList();
                };
                //初始化
                var targetList = new List<int>();
                //单元内力存在
                if (this.forceXML != null) targetList = this.forceXML.TagList;
                //截面分析结果
                if (this.deformXML != null)
                {
                    targetList = targetList.Count == 0 ? this.deformXML.TagList :
                        FilterFuc(this.deformXML.TagList, targetList);
                }
                //材料分析结果
                if (this.strainXML != null)
                {
                    //存在筛选条件
                    if (targetList.Count != 0) targetList = FilterFuc(this.strainXML.TagList, targetList);
                    //为空但仅有该项分析结果
                    else if (this.deformXML == null && this.forceXML == null)
                        targetList = this.strainXML.TagList;
                }
                return targetList;
            }
        }

        /// <summary>
        /// 数据量大小
        /// </summary>
        public int Count
        {
            get
            {
                return this.Datas.Count;
            }
        }

        #endregion

        /// <summary>
        /// 空的构造函数
        /// </summary>
        public ElementDataSet()
        {
            this.Datas = new List<ElementData>();
        }

        /// <summary>
        /// 构造函数 X Y轴值
        /// </summary>
        /// <param name="xmlX"></param>
        /// <param name="xmlY"></param>
        public ElementDataSet(ElementXML xmlX, ElementXML xmlY)
        {
            //构造
            this.forceXML = xmlX;
            this.deformXML = xmlY;
            //设定单元序列结果
            this.SetDatas();
        }

        /// <summary>
        /// 设定分析结果
        /// </summary>
        /// <returns></returns>
        public int SetDatas()
        {
            //初始化
            this.Datas = new List<ElementData>();
            //遍历相同的编号列表
            this.SameTagFromXML.ForEach(tag =>
            {
                //初始化
                var data = new ElementData { ID = tag };
                //设定结果
                if (this.forceXML != null && this.forceXML.ContainsKey(tag))
                    data.forceResponse = this.forceXML[tag];
                if (this.deformXML != null && this.deformXML.ContainsKey(tag))
                    data.defromResponse = this.deformXML[tag];
                if (this.strainXML != null && this.strainXML.ContainsKey(tag))
                    data.strainResponse = this.strainXML[tag];
                //添加数据
                this.Datas.Add(data);
            });
            //返回数目
            return this.Datas.Count;
        }
    }

    /// <summary>
    /// 单元响应 多结果合并
    /// </summary>
    public class ElementData
    {
        /// <summary>
        /// 结果枚举
        /// </summary>
        public enum ResultType
        {
            /// <summary>
            /// 力
            /// </summary>
            Force = 1,

            /// <summary>
            /// 变形
            /// </summary>
            Deform = 2,

            /// <summary>
            /// 应变
            /// </summary>
            Strain = 3,
        }

        #region Variables

        /// <summary>
        /// 单元编号
        /// </summary>
        public int ID { set; get; }

        /// <summary>
        /// 单元响应
        /// </summary>
        public Response forceResponse { set; get; }

        /// <summary>
        /// 截面响应
        /// </summary>
        public Response defromResponse { set; get; }

        /// <summary>
        /// 纤维响应
        /// </summary>
        public Response strainResponse { set; get; }

        #endregion

        /// <summary>
        /// 获得响应
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public Response this[ResultType type]
        {
            get
            {
                switch(type)
                {
                    case ResultType.Force: return this.forceResponse;
                    case ResultType.Strain: return this.strainResponse;
                    case ResultType.Deform: return this.defromResponse;
                    default: return null;
                }
            }
        }

        /// <summary>
        /// 获得响应时程
        /// </summary>
        /// <param name="type"></param>
        /// <param name="descp"></param>
        /// <returns></returns>
        public List<float> this[ResultType type, string descp]
        {
            get
            {
                return this[type][descp];
            }
        }

        /// <summary>
        /// 数据
        /// </summary>
        public GridViewDatas Data(string xDescp, string yDescp)
        {
            //初始化
            var data = new GridViewDatas(this.ID.ToString());
            //获得列表
            var xList = this[ ResultType.Force, xDescp];
            var yList = this[ ResultType.Deform, yDescp];
            //判断两列数据点数目是否相同
            if (xList.Count != yList.Count) return data;
            //X轴分析结果
            data.Add(new GridViewColumn(xList, demical: -1, format: "E2",
                titleName: string.Format("{0}_{1}", this.ID, xDescp)));
            //Y轴分析结果
            data.Add(new GridViewColumn(yList, demical: -1, format: "E2",
                titleName: string.Format("{0}_{1}", this.ID, yDescp)));
            //返回数据
            return data;
        }

        /// <summary>
        /// 空的构造函数
        /// </summary>
        public ElementData()
        {

        }
    }
}
